bitkeeper revision 1.1389.9.1 (427ba309i_zOrtoMDOTBwa5_vBiEXQ)
authordjm@kirby.fc.hp.com <djm@kirby.fc.hp.com>
Fri, 6 May 2005 17:02:01 +0000 (17:02 +0000)
committerdjm@kirby.fc.hp.com <djm@kirby.fc.hp.com>
Fri, 6 May 2005 17:02:01 +0000 (17:02 +0000)
Add support for privified mov-from-pmd
Add counters for privified-fc and privified-cpuid
Add optional support for counting addresses of privops
Remove unnecessary PCI stuff
Add optional heartbeat console output
Signed-off by: Dan Magenheimer <dan.magenheimer@hp.com>

xen/arch/ia64/privop.c
xen/arch/ia64/vcpu.c
xen/arch/ia64/xenmisc.c
xen/arch/ia64/xentime.c
xen/include/asm-ia64/config.h
xen/include/asm-ia64/vcpu.h

index 0b59b60ad8084a1c4ad8c7ee0d80fe157f395d1b..11ef17310f28db4592e2a25494faa21c405be2ba 100644 (file)
@@ -417,10 +417,17 @@ IA64FAULT priv_mov_from_pmc(VCPU *vcpu, INST64 inst)
        UINT64 val;
        IA64FAULT fault;
        
-       fault = vcpu_get_pmc(vcpu,vcpu_get_gr(vcpu,inst.M43.r3),&val);
-       if (fault == IA64_NO_FAULT)
-               return vcpu_set_gr(vcpu, inst.M43.r1, val);
-       else return fault;
+       if (inst.M43.r1 > 63) { // privified mov from pmd
+               fault = vcpu_get_pmd(vcpu,vcpu_get_gr(vcpu,inst.M43.r3),&val);
+               if (fault == IA64_NO_FAULT)
+                       return vcpu_set_gr(vcpu, inst.M43.r1-64, val);
+       }
+       else {
+               fault = vcpu_get_pmc(vcpu,vcpu_get_gr(vcpu,inst.M43.r3),&val);
+               if (fault == IA64_NO_FAULT)
+                       return vcpu_set_gr(vcpu, inst.M43.r1, val);
+       }
+       return fault;
 }
 
 unsigned long from_cr_cnt[128] = { 0 };
@@ -531,6 +538,8 @@ struct {
        unsigned long bsw0;
        unsigned long bsw1;
        unsigned long cover;
+       unsigned long fc;
+       unsigned long cpuid;
        unsigned long Mpriv_cnt[64];
 } privcnt = { 0 };
 
@@ -631,7 +640,11 @@ priv_handle_op(VCPU *vcpu, REGS *regs, int privlvl)
                                else x6 = 0x1a;
                        }
                }
-               privcnt.Mpriv_cnt[x6]++;
+               if (x6 == 52 && inst.M28.r3 > 63)
+                       privcnt.fc++;
+               else if (x6 == 16 && inst.M43.r3 > 63)
+                       privcnt.cpuid++;
+               else privcnt.Mpriv_cnt[x6]++;
                return (*pfunc)(vcpu,inst);
                break;
            case B:
@@ -826,6 +839,12 @@ int dump_privop_counts(char *buf)
        if (privcnt.cover)
                s += sprintf(s,"%10d  %s [%d%%]\r\n", privcnt.cover,
                        "cover", (privcnt.cover*100L)/sum);
+       if (privcnt.fc)
+               s += sprintf(s,"%10d  %s [%d%%]\r\n", privcnt.fc,
+                       "privified-fc", (privcnt.fc*100L)/sum);
+       if (privcnt.cpuid)
+               s += sprintf(s,"%10d  %s [%d%%]\r\n", privcnt.cpuid,
+                       "privified-getcpuid", (privcnt.cpuid*100L)/sum);
        for (i=0; i < 64; i++) if (privcnt.Mpriv_cnt[i]) {
                if (!Mpriv_str[i]) s += sprintf(s,"PRIVSTRING NULL!!\r\n");
                else s += sprintf(s,"%10d  %s [%d%%]\r\n", privcnt.Mpriv_cnt[i],
@@ -864,6 +883,7 @@ int zero_privop_counts(char *buf)
        privcnt.ssm = 0; privcnt.rsm = 0;
        privcnt.rfi = 0; privcnt.bsw0 = 0;
        privcnt.bsw1 = 0; privcnt.cover = 0;
+       privcnt.fc = 0; privcnt.cpuid = 0;
        for (i=0; i < 64; i++) privcnt.Mpriv_cnt[i] = 0;
        for (j=0; j < 128; j++) from_cr_cnt[j] = 0;
        for (j=0; j < 128; j++) to_cr_cnt[j] = 0;
@@ -871,12 +891,61 @@ int zero_privop_counts(char *buf)
        return s - buf;
 }
 
+#ifdef PRIVOP_ADDR_COUNT
+
+extern struct privop_addr_count privop_addr_counter[];
+
+void privop_count_addr(unsigned long iip, int inst)
+{
+       struct privop_addr_count *v = &privop_addr_counter[inst];
+       int i;
+
+       for (i = 0; i < PRIVOP_COUNT_NADDRS; i++) {
+               if (!v->addr[i]) { v->addr[i] = iip; v->count[i]++; return; }
+               else if (v->addr[i] == iip)  { v->count[i]++; return; }
+       }
+       v->overflow++;;
+}
+
+int dump_privop_addrs(char *buf)
+{
+       int i,j;
+       char *s = buf;
+       s += sprintf(s,"Privop addresses:\r\n");
+       for (i = 0; i < PRIVOP_COUNT_NINSTS; i++) {
+               struct privop_addr_count *v = &privop_addr_counter[i];
+               s += sprintf(s,"%s:\n",v->instname);
+               for (j = 0; j < PRIVOP_COUNT_NADDRS; j++) {
+                       if (!v->addr[j]) break;
+                       s += sprintf(s," @%p #%ld\n",v->addr[j],v->count[j]);
+               }
+               if (v->overflow) 
+                       s += sprintf(s," other #%ld\n",v->overflow);
+       }
+       return s - buf;
+}
+
+void zero_privop_addrs(void)
+{
+       int i,j;
+       for (i = 0; i < PRIVOP_COUNT_NINSTS; i++) {
+               struct privop_addr_count *v = &privop_addr_counter[i];
+               for (j = 0; j < PRIVOP_COUNT_NADDRS; j++)
+                       v->addr[j] = v->count[j] = 0;
+               v->overflow = 0;
+       }
+}
+#endif
+
 #define TMPBUFLEN 8*1024
 int dump_privop_counts_to_user(char __user *ubuf, int len)
 {
        char buf[TMPBUFLEN];
        int n = dump_privop_counts(buf);
 
+#ifdef PRIVOP_ADDR_COUNT
+       n += dump_privop_addrs(buf + n);
+#endif
        if (len < TMPBUFLEN) return -1;
        if (__copy_to_user(ubuf,buf,n)) return -1;
        return n;
@@ -887,6 +956,9 @@ int zero_privop_counts_to_user(char __user *ubuf, int len)
        char buf[TMPBUFLEN];
        int n = zero_privop_counts(buf);
 
+#ifdef PRIVOP_ADDR_COUNT
+       zero_privop_addrs();
+#endif
        if (len < TMPBUFLEN) return -1;
        if (__copy_to_user(ubuf,buf,n)) return -1;
        return n;
index d1769a20c3db5761d887c478cfdd1551b4ea891d..f5c3f458b3bb724b1e490938376a7a93ce9921d9 100644 (file)
@@ -37,6 +37,17 @@ typedef      union {
 
 #define STATIC
 
+#ifdef PRIVOP_ADDR_COUNT
+struct privop_addr_count privop_addr_counter[PRIVOP_COUNT_NINSTS] = {
+       { "rsm", { 0 }, { 0 }, 0 },
+       { "ssm", { 0 }, { 0 }, 0 }
+};
+extern void privop_count_addr(unsigned long addr, int inst);
+#define        PRIVOP_COUNT_ADDR(regs,inst) privop_count_addr(regs->cr_iip,inst)
+#else
+#define        PRIVOP_COUNT_ADDR(x,y) do {} while (0)
+#endif
+
 unsigned long vcpu_verbose = 0;
 #define verbose(a...) do {if (vcpu_verbose) printf(a);} while(0)
 
@@ -77,30 +88,20 @@ vcpu_set_gr(VCPU *vcpu, unsigned reg, UINT64 value)
 IA64FAULT vcpu_set_ar(VCPU *vcpu, UINT64 reg, UINT64 val)
 {
        if (reg == 44) return (vcpu_set_itc(vcpu,val));
-       if (reg == 27) return (IA64_ILLOP_FAULT);
-       if (reg > 7) return (IA64_ILLOP_FAULT);
-       PSCB(vcpu,krs[reg]) = val;
-#if 0
-// for now, privify kr read's so all kr accesses are privileged
-       switch (reg) {
-             case 0: asm volatile ("mov ar.k0=%0" :: "r"(val)); break;
-             case 1: asm volatile ("mov ar.k1=%0" :: "r"(val)); break;
-             case 2: asm volatile ("mov ar.k2=%0" :: "r"(val)); break;
-             case 3: asm volatile ("mov ar.k3=%0" :: "r"(val)); break;
-             case 4: asm volatile ("mov ar.k4=%0" :: "r"(val)); break;
-             case 5: asm volatile ("mov ar.k5=%0" :: "r"(val)); break;
-             case 6: asm volatile ("mov ar.k6=%0" :: "r"(val)); break;
-             case 7: asm volatile ("mov ar.k7=%0" :: "r"(val)); break;
-             case 27: asm volatile ("mov ar.cflg=%0" :: "r"(val)); break;
-       }
-#endif
+       else if (reg == 27) return (IA64_ILLOP_FAULT);
+       else if (reg == 24)
+           printf("warning: setting ar.eflg is a no-op; no IA-32 support\n");
+       else if (reg > 7) return (IA64_ILLOP_FAULT);
+       else PSCB(vcpu,krs[reg]) = val;
        return IA64_NO_FAULT;
 }
 
 IA64FAULT vcpu_get_ar(VCPU *vcpu, UINT64 reg, UINT64 *val)
 {
-       if (reg > 7) return (IA64_ILLOP_FAULT);
-       *val = PSCB(vcpu,krs[reg]);
+       if (reg == 24)
+           printf("warning: getting ar.eflg is a no-op; no IA-32 support\n");
+       else if (reg > 7) return (IA64_ILLOP_FAULT);
+       else *val = PSCB(vcpu,krs[reg]);
        return IA64_NO_FAULT;
 }
 
@@ -124,6 +125,7 @@ IA64FAULT vcpu_reset_psr_sm(VCPU *vcpu, UINT64 imm24)
        struct ia64_psr psr, imm, *ipsr;
        REGS *regs = vcpu_regs(vcpu);
 
+       PRIVOP_COUNT_ADDR(regs,_RSM);
        // TODO: All of these bits need to be virtualized
        // TODO: Only allowed for current vcpu
        __asm__ __volatile ("mov %0=psr;;" : "=r"(psr) :: "memory");
@@ -158,6 +160,7 @@ IA64FAULT vcpu_set_psr_sm(VCPU *vcpu, UINT64 imm24)
        REGS *regs = vcpu_regs(vcpu);
        UINT64 mask, enabling_interrupts = 0;
 
+       PRIVOP_COUNT_ADDR(regs,_SSM);
        // TODO: All of these bits need to be virtualized
        __asm__ __volatile ("mov %0=psr;;" : "=r"(psr) :: "memory");
        imm = *(struct ia64_psr *)&imm24;
index fe9f3442d20d1ed3c5349384a8f87ff264ce3066..09dfc2a7b9bc41f5deb559fb13d69df55da7076b 100644 (file)
@@ -132,73 +132,6 @@ void free_page_type(struct pfn_info *page, unsigned int type)
        dummy();
 }
 
-///////////////////////////////
-// from arch/x86/pci.c
-///////////////////////////////
-
-int
-pcibios_prep_mwi (struct pci_dev *dev)
-{
-       dummy();
-}
-
-///////////////////////////////
-// from arch/x86/pci-irq.c
-///////////////////////////////
-
-void pcibios_enable_irq(struct pci_dev *dev)
-{
-       dummy();
-}
-
-///////////////////////////////
-// from arch/ia64/pci-pc.c
-///////////////////////////////
-
-#include <xen/pci.h>
-
-int pcibios_enable_device(struct pci_dev *dev, int mask)
-{
-       dummy();
-       return 0;
-}
-
-int (*pci_config_read)(int seg, int bus, int dev, int fn, int reg, int len, u32 *value) = NULL;
-int (*pci_config_write)(int seg, int bus, int dev, int fn, int reg, int len, u32 value) = NULL;
-
-//struct pci_fixup pcibios_fixups[] = { { 0 } };
-struct pci_fixup pcibios_fixups[] = { { 0 } };
-
-void
-pcibios_align_resource(void *data, struct resource *res,
-                      unsigned long size, unsigned long align)
-{
-       dummy();
-}
-
-void
-pcibios_update_resource(struct pci_dev *dev, struct resource *root,
-                       struct resource *res, int resource)
-{
-       dummy();
-}
-
-void __devinit  pcibios_fixup_bus(struct pci_bus *b)
-{
-       dummy();
-}
-
-void __init pcibios_init(void)
-{
-       dummy();
-}
-
-char * __devinit  pcibios_setup(char *str)
-{
-       dummy();
-       return 0;
-}
-
 ///////////////////////////////
 // from arch/ia64/traps.c
 ///////////////////////////////
@@ -206,7 +139,7 @@ char * __devinit  pcibios_setup(char *str)
 void show_registers(struct pt_regs *regs)
 {
        printf("*** ADD REGISTER DUMP HERE FOR DEBUGGING\n");
-}      
+}
 
 ///////////////////////////////
 // from common/keyhandler.c
index 20d13eb7efea14256bf8746b5f75d4d85d883b7f..a3790b457703c7a3dbfa3344bbd9a4e8834d84a6 100644 (file)
@@ -84,6 +84,17 @@ xen_timer_interrupt (int irq, void *dev_id, struct pt_regs *regs)
 {
        unsigned long new_itm;
 
+#define HEARTBEAT_FREQ 16      // period in seconds
+#ifdef HEARTBEAT_FREQ
+       static long count = 0;
+       if (!(++count & ((HEARTBEAT_FREQ*1024)-1))) {
+               printf("Heartbeat... iip=%p,psr.i=%d,pend=%d\n",
+                       regs->cr_iip,
+                       current->vcpu_info->arch.interrupt_delivery_enabled,
+                       current->vcpu_info->arch.pending_interruption);
+               count = 0;
+       }
+#endif
 #ifndef XEN
        if (unlikely(cpu_is_offline(smp_processor_id()))) {
                return IRQ_HANDLED;
index 74dbb3a4e5ec15ae555f729af59a47814703d686..0a3672b18e2766dda651c127e0b28d2bbf10cae7 100644 (file)
@@ -174,12 +174,6 @@ struct device {
 #endif
 };
 
-// from linux/include/linux/pci.h
-struct pci_bus_region {
-       unsigned long start;
-       unsigned long end;
-};
-
 // warning: unless search_extable is declared, the return value gets
 // truncated to 32-bits, causing a very strange error in privop handling
 struct exception_table_entry;
index 6ee2e73ddec774dbc108985dec6c23e41726f6c8..e3bcfbde7965bc32d9da99730f606dae7989fd7c 100644 (file)
@@ -21,6 +21,21 @@ typedef struct pt_regs REGS;
 //#define vcpu_regs(vcpu)              &((struct spk_thread_t *)vcpu)->thread_regs
 //#define vcpu_thread(vcpu)    ((struct spk_thread_t *)vcpu)
 
+#define PRIVOP_ADDR_COUNT
+#ifdef PRIVOP_ADDR_COUNT
+#define _RSM 0
+#define _SSM 1
+#define PRIVOP_COUNT_NINSTS 2
+#define PRIVOP_COUNT_NADDRS 30
+
+struct privop_addr_count {
+       char *instname;
+       unsigned long addr[PRIVOP_COUNT_NADDRS];
+       unsigned long count[PRIVOP_COUNT_NADDRS];
+       unsigned long overflow;
+};
+#endif
+
 /* general registers */
 extern UINT64 vcpu_get_gr(VCPU *vcpu, unsigned reg);
 extern IA64FAULT vcpu_set_gr(VCPU *vcpu, unsigned reg, UINT64 value);